package com.googlecode.jlogindexer.log4j;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.Transform;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

public class JSONLayout extends Layout implements JLogIndexerConstants {

	private final int DEFAULT_SIZE = 256;
	private final int UPPER_LIMIT = 2048;

	private StringBuilder buffer = new StringBuilder(DEFAULT_SIZE);

	public void activateOptions() {
	}

	public String format(LoggingEvent event) {

		// Arun -- This buffer reset section is shamelessly stolen from
		// XMLLayout

		// Reset working buffer. If the buffer is too large, then we need a new
		// one in order to avoid the penalty of creating a large array.

		
		if (buffer.capacity() > UPPER_LIMIT) {
			buffer = new StringBuilder(DEFAULT_SIZE);
		} else {
			buffer.setLength(0);
		}

		/*
		 * Targetted output
		 * 
		 * { "event": { "logger": "com.googlecode.jlogindexer.AutoLogger",
		 * "timestamp": 1299692904875, "level": "WARN", "thread": "main",
		 * "message": "This is a warning message", "class":
		 * "com.googlecode.jlogindexer.AutoLogger", "method": "beginLogging",
		 * "file": "AutoLogger.java", "line": 28 } }
		 */

		LocationInfo locationInfo = event.getLocationInformation();

		buffer.append(OPEN_BRACES);
		buffer.append(EVENT).append(OPEN_BRACES);
		buffer.append(LOGGER).append(DOUBLE_QUOTE).append(event.getLoggerName()).append(DOUBLE_QUOTE).append(COMMA);
		buffer.append(TIMESTAMP).append(event.timeStamp).append(COMMA);
		buffer.append(LEVEL).append(DOUBLE_QUOTE).append(event.getLevel()).append(DOUBLE_QUOTE).append(COMMA);
		buffer.append(THREAD).append(DOUBLE_QUOTE).append(event.getThreadName()).append(DOUBLE_QUOTE).append(COMMA);

		// Message
		buffer.append(MESSAGE).append(DOUBLE_QUOTE);
		System.out.println("EVENT RENDERED MESSAGE "
				+ event.getRenderedMessage());
		buffer.append(StringEscapeUtils.escapeJavaScript(event
				.getRenderedMessage()));
		buffer.append(DOUBLE_QUOTE).append(COMMA);

		// Error trace
		String[] s = event.getThrowableStrRep();
		if (s != null) {
			buffer.append(THROWABLE).append(DOUBLE_QUOTE);
			for (int i = 0; i < s.length; i++) {
				buffer.append(s[i]);
				buffer.append("\r\n");
			}
			buffer.append(DOUBLE_QUOTE).append(CLOSE_BRACES).append(COMMA);
		}

		buffer.append(CLASS).append(DOUBLE_QUOTE).append(locationInfo.getClassName()).append(DOUBLE_QUOTE).append(COMMA);
		buffer.append(METHOD).append(DOUBLE_QUOTE).append(locationInfo.getMethodName()).append(DOUBLE_QUOTE).append(COMMA);
		buffer.append(FILE).append(DOUBLE_QUOTE).append(locationInfo.getFileName()).append(DOUBLE_QUOTE).append(COMMA);
		buffer.append(LINE).append(locationInfo.getLineNumber());
		buffer.append(CLOSE_BRACES).append(CLOSE_BRACES);
		buffer.append(event.getLoggerName()).append(DOUBLE_QUOTE).append(COMMA);

		return buffer.toString();
	}

	/**
	 * The XMLLayout prints and does not ignore exceptions. Hence the return
	 * value <code>false</code>.
	 */
	public boolean ignoresThrowable() {
		return false;
	}
}
